// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <nebula/types/meta/list_type.h>

namespace nebula {

    constexpr Type::type ListType::type_id;
    constexpr Type::type LargeListType::type_id;
    constexpr Type::type ListViewType::type_id;
    constexpr Type::type LargeListViewType::type_id;

    constexpr Type::type FixedSizeListType::type_id;

    std::string ListType::to_string(bool show_metadata) const {
        std::stringstream s;
        s << "list<" << value_field()->to_string(show_metadata) << ">";
        return s.str();
    }

    std::string LargeListType::to_string(bool show_metadata) const {
        std::stringstream s;
        s << "large_list<" << value_field()->to_string(show_metadata) << ">";
        return s.str();
    }

    std::string ListViewType::to_string(bool show_metadata) const {
        std::stringstream s;
        s << "list_view<" << value_field()->to_string(show_metadata) << ">";
        return s.str();
    }

    std::string LargeListViewType::to_string(bool show_metadata) const {
        std::stringstream s;
        s << "large_list_view<" << value_field()->to_string(show_metadata) << ">";
        return s.str();
    }

    std::string FixedSizeListType::to_string(bool show_metadata) const {
        std::stringstream s;
        s << "fixed_size_list<" << value_field()->to_string(show_metadata) << ">[" << list_size_
          << "]";
        return s.str();
    }

    std::string LargeListViewType::compute_fingerprint() const {
        const auto &child_fingerprint = get_value_type()->fingerprint();
        if (!child_fingerprint.empty()) {
            std::stringstream ss;
            ss << type_id_fingerprint(*this);
            if (value_field()->nullable()) {
                ss << 'n';
            } else {
                ss << 'N';
            }
            ss << '{' << child_fingerprint << '}';
            return ss.str();
        }
        return "";
    }

    std::string FixedSizeListType::compute_fingerprint() const {
        const auto &child_fingerprint = get_value_type()->fingerprint();
        if (!child_fingerprint.empty()) {
            std::stringstream ss;
            ss << type_id_fingerprint(*this);
            if (value_field()->nullable()) {
                ss << 'n';
            } else {
                ss << 'N';
            }
            ss << "[" << list_size_ << "]"
               << "{" << child_fingerprint << "}";
            return ss.str();
        }
        return "";
    }

    std::string ListType::compute_fingerprint() const {
        const auto &child_fingerprint = get_value_type()->fingerprint();
        if (!child_fingerprint.empty()) {
            std::stringstream ss;
            ss << type_id_fingerprint(*this);
            if (value_field()->nullable()) {
                ss << 'n';
            } else {
                ss << 'N';
            }
            ss << '{' << child_fingerprint << '}';
            return ss.str();
        }
        return "";
    }

    std::string LargeListType::compute_fingerprint() const {
        const auto &child_fingerprint = get_value_type()->fingerprint();
        if (!child_fingerprint.empty()) {
            std::stringstream ss;
            ss << type_id_fingerprint(*this);
            if (value_field()->nullable()) {
                ss << 'n';
            } else {
                ss << 'N';
            }
            ss << '{' << child_fingerprint << '}';
            return ss.str();
        }
        return "";
    }

    std::string ListViewType::compute_fingerprint() const {
        const auto &child_fingerprint = get_value_type()->fingerprint();
        if (!child_fingerprint.empty()) {
            std::stringstream ss;
            ss << type_id_fingerprint(*this);
            if (value_field()->nullable()) {
                ss << 'n';
            } else {
                ss << 'N';
            }
            ss << '{' << child_fingerprint << '}';
            return ss.str();
        }
        return "";
    }


}  // namespace nebula
